#Binary parser template

import os, sys
from Sanae3D.lib.StructReader import StructReader
from Sanae3D.lib.ModelObject import Model3D

class RustyHearts_MGM(Model3D):
    '''Replace 'RustyHearts_MGM' with a suitable name of your choice. Try to follow
    the standard: GameName_FormatExt'''
    
    def __init__(self, obj3D=None, outFile=None, inFile=None):
        
        super(RustyHearts_MGM,self).__init__("XAC")
        self.obj3D = obj3D
        self.inFile = inFile
        self.outFile = outFile
        
    def read_name(self, n):
        
        name = []

        for i in range(n):
            name.append(self.inFile.read_char())
            self.inFile.seek(1, 1)
        return ''.join(name)
    
    def read_unistring(self):
        
        name = []
        char = self.inFile.read_char()
        while char != "\x00":
            name.append(char)
            self.inFile.seek(1, 1)
            char = self.inFile.read_char()
        return ''.join(name)
    
    def parse_materials(self):
        
        print "materials!", self.inFile.tell()
        unk, numMat = self.inFile.read_long(2)
        for i in range(numMat):
            unk1, len1, len2 = self.inFile.read_long(3)
            name1 = self.read_name(len1)
            matName = self.read_name(len2)
            
            self.inFile.seek(5, 1)
            self.inFile.read_long(3)
            
            for j in xrange(8):
                self.inFile.seek(52, 1)
            
            print self.inFile.tell()
            print self.inFile.seek(11, 1)
            self.inFile.seek(21, 1)
            texName = self.read_unistring()
            
            self.create_material(i)
            self.add_material_name(i, matName)
            self.add_texture_name(i, os.path.basename(texName))
            break
    
    def parse_vertices(self, meshName, numVerts):
        
        for i in range(numVerts):
            vx, vy, vz = self.inFile.read_float(3)
            nx, ny, nz = self.inFile.read_float(3)
            tu, tv = self.inFile.read_float(2)
            
            #tv *= -1
            vx *= -1
            
            self.create_vertex(meshName, i)
            self.add_coords(meshName, i, [vx, vy, vz])
            self.add_vert_normals(meshName, i, [nx, ny, nz])
            self.add_vert_uv(meshName, i, [tu, tv])
            
    def parse_faces(self, meshName, numFaces, matNum):
        
        for i in range(numFaces):
            v1, v2, v3 = self.inFile.read_short(3)
            self.create_face(meshName, i)
            self.add_face_verts(meshName, i, [v1, v2, v3])
            self.add_face_material(meshName, i, matNum)
            
    def parse_mesh_5(self):
        
        len1, unk1, unk2, unk3 = self.inFile.read_long(4)
        name1 = self.read_name(len1)
        numMesh = self.inFile.read_long()
        
        for i in range(numMesh):
            len2 = self.inFile.read_long()
            name = self.read_name(len2)
            meshName = '%s[%d]' %(name, i)
            self.create_object(meshName)
            #print meshName
            
            numVerts, numFaces = self.inFile.read_long(2)
            self.inFile.seek(0x13, 1)
            self.parse_vertices(meshName, numVerts)
            self.inFile.seek(36, 1)
            self.parse_faces(meshName, numFaces)
        
    def parse_mesh_6(self):
        
        print self.inFile.tell()
        len1, len2, unk1, unk2 = self.inFile.read_long(4)
        print len1, len2
        meshName = self.read_name(len1)
        name2 = self.read_name(len2)
        
        self.create_object(meshName)
        
        matNum = self.inFile.read_long() - 1
        matNameLen = self.inFile.read_long()
        matName = self.read_name(matNameLen)
        
        self.add_material_name(matNum, matName)
        
        numVerts, numFaces = self.inFile.read_long(2)
        self.inFile.seek(0x13,1)
        
        self.parse_vertices(meshName, numVerts)
        self.parse_faces(meshName, numFaces, matNum)
        
    def parse_file(self):
        '''Main parser method. Can be replaced'''
        
        magic = self.inFile.read_string(5)
        count1, count2 = self.inFile.read_long(2)
        
        offsets = self.inFile.read_long(count2)
        sizes = self.inFile.read_long(count2)
        types = self.inFile.read_long(count2)
        
        #print offsets
        #print sizes
        #print types
        
        for i in range(len(types)):
            self.inFile.seek(offsets[i])
            if types[i] == 6:                
                self.parse_mesh_6()
            elif types[i] == 5:
                self.parse_mesh_5()
            elif types[i] == 1:
                self.parse_materials()
        
def read_file(path):
    '''Read the file'''
    
    openFile = StructReader(open(path, 'rb'))
    obj = RustyHearts_MGM(inFile=openFile)
    obj.parse_file()
    openFile.close()
    return obj

def write_file(path):
    
    pass

def definitions():
    '''Return the header, extension, and a description of the format'''
    
    return "DoBal", "MGM", ""

if __name__ == '__main__':
    
    file1 = "bomb_weapon.mgm"
    file2 = "goat01.mgm"
    obj = read_file(file2)